package 结构性模式

import java.util.*


/**
 * 将对象组合成树形结构以表示“部分-整体”的层次结构，使得用户对单个对象和组合对象的使用具有一致性。
 */
interface Node {
    fun add(node: Node): Node
    fun children(): List<Node>
    fun toXml(): String
}

class ElementNode(private val name: String) : Node {
    private val list = ArrayList<Node>()
    override fun add(node: Node): Node {
        list.add(node)
        return this
    }

    override fun children(): List<Node> {
        return list
    }

    override fun toXml(): String {
        val start = "<$name>\n"
        val end = "</$name>\n"
        val sj = StringJoiner("", start, end)
        list.forEach { node ->
            sj.add(node.toXml() + "\n")
        }
        return sj.toString()
    }
}

class TextNode(private val text: String) : Node {
    override fun add(node: Node): Node {
        throw UnsupportedOperationException()
    }

    override fun children(): List<Node> {
        return arrayListOf()
    }

    override fun toXml(): String {
        return text
    }
}

class CommentNode(private val text: String) : Node {
    override fun add(node: Node): Node {
        throw UnsupportedOperationException()
    }

    override fun children(): List<Node> {
        return arrayListOf()
    }

    override fun toXml(): String {
        return "<!-- $text -->"
    }
}

fun main() {
    val root: Node = ElementNode("school")
    root.add(ElementNode("classA")
            .add(TextNode("Tom"))
            .add(TextNode("Alice")))
    root.add(ElementNode("classB")
            .add(TextNode("Bob"))
            .add(TextNode("Grace"))
            .add(CommentNode("comment...")))
    println(root.toXml())
}